home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Astrolog (Version 4.40) File: charts3.c
- **
- ** IMPORTANT NOTICE: The graphics database and chart display routines
- ** used in this program are Copyright (C) 1991-1995 by Walter D. Pullen
- ** (astara@u.washington.edu). Permission is granted to freely use and
- ** distribute these routines provided one doesn't sell, restrict, or
- ** profit from them in any way. Modification is allowed provided these
- ** notices remain with any altered or edited versions of the program.
- **
- ** The main planetary calculation routines used in this program have
- ** been Copyrighted and the core of this program is basically a
- ** conversion to C of the routines created by James Neely as listed in
- ** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
- ** available from Matrix Software. The copyright gives us permission to
- ** use the routines for personal use but not to sell them or profit from
- ** them in any way.
- **
- ** The PostScript code within the core graphics routines are programmed
- ** and Copyright (C) 1992-1993 by Brian D. Willoughby
- ** (brianw@sounds.wa.com). Conditions are identical to those above.
- **
- ** The extended accurate ephemeris databases and formulas are from the
- ** calculation routines in the program "Placalc" and are programmed and
- ** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
- ** (alois@azur.ch). The use of that source code is subject to
- ** regulations made by Astrodienst Zurich, and the code is not in the
- ** public domain. This copyright notice must not be changed or removed
- ** by any user of this program.
- **
- ** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
- ** X Window graphics initially programmed 10/23-29/1991.
- ** PostScript graphics initially programmed 11/29-30/1992.
- ** Last code change made 1/29/1995.
- */
-
- #include "astrolog.h"
-
-
- /*
- ******************************************************************************
- ** Multiple Chart Scanning Routines.
- ******************************************************************************
- */
-
- /* Search through a day, and print out the times of exact aspects among the */
- /* planets during that day, as specified with the -d switch, as well as the */
- /* times when a planet changes sign or direction. To do this, we cast charts */
- /* for the beginning and end of the day, or a part of a day, and do a linear */
- /* equation check to see if anything exciting happens during the interval. */
- /* (This is probably the single most complicated procedure in the program.) */
-
- void ChartInDaySearch(fProg)
- bool fProg;
- {
- char sz[cchSzDef];
- int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY],
- sign1[MAXINDAY], sign2[MAXINDAY], D1, D2, occurcount, division, div,
- fYear, yea0, yea1, yea2, i, j, k, l, s1, s2;
- real time[MAXINDAY], divsiz, d1, d2, e1, e2, f1, f2, g;
-
- /* If parameter 'fProg' is set, look for changes in a progressed chart. */
-
- fYear = us.fInDayMonth && (Mon2 == 0);
- division = (fYear || fProg) ? 1 : us.nDivision;
- divsiz = 24.0 / (real)division*60.0;
-
- /* If -dY in effect, then search through a range of years. */
-
- yea1 = fProg ? Yea2 : Yea;
- yea2 = fYear ? (yea1 + us.nEphemYears - 1) : yea1;
- for (yea0 = yea1; yea0 <= yea2; yea0++) {
-
- /* If -dm in effect, then search through the whole month, day by day. */
-
- if (us.fInDayMonth) {
- D1 = 1;
- if (fYear) {
- Mon2 = 1; D2 = DayInYearHi(yea0);
- } else
- D2 = DayInMonth(fProg ? Mon2 : Mon, yea0);
- } else
- D1 = D2 = Day;
-
- /* Start searching the day or days in question for exciting stuff. */
-
- for (Day2 = D1; Day2 <= D2; Day2 = AddDay(Mon, Day2, yea0, 1)) {
- occurcount = 0;
-
- /* Cast chart for beginning of day and store it for future use. */
-
- SetCI(ciCore, fYear ? Mon2 : Mon, Day2, yea0, 0.0, Dst, Zon, Lon, Lat);
- if (us.fProgress = fProg) {
- is.JDp = MdytszToJulian(Mon2, DD, yea0, 0.0, Dst, Zon);
- ciCore = ciMain;
- }
- CastChart(fTrue);
- for (i = 1; i <= cSign; i++) {
- cp2.cusp[i] = house[i];
- cp2.house[i] = inhouse[i];
- }
- for (i = 1; i <= cObj; i++) {
- cp2.obj[i] = planet[i];
- cp2.dir[i] = ret[i];
- }
-
- /* Now divide the day into segments and search each segment in turn. */
- /* More segments is slower, but has slightly better time accuracy. */
-
- for (div = 1; div <= division; div++) {
-
- /* Cast the chart for the ending time of the present segment. The */
- /* beginning time chart is copied from the previous end time chart. */
-
- SetCI(ciCore, fYear ? Mon2 : Mon, Day2, yea0,
- DegToDec(24.0*(real)div/(real)division), Dst, Zon, Lon, Lat);
- if (fProg) {
- is.JDp = MdytszToJulian(Mon2, DD+1, yea0, 0.0, Dst, Zon);
- ciCore = ciMain;
- }
- CastChart(fTrue);
- for (i = 1; i <= cSign; i++) {
- cp1.cusp[i] = cp2.cusp[i]; cp1.house[i] = cp2.house[i];
- cp2.cusp[i] = house[i]; cp2.house[i] = inhouse[i];
- }
- for (i = 1; i <= cObj; i++) {
- cp1.obj[i] = cp2.obj[i]; cp1.dir[i] = cp2.dir[i];
- cp2.obj[i] = planet[i]; cp2.dir[i] = ret[i];
- }
-
- /* Now search through the present segment for anything exciting. */
-
- for (i = 1; i <= cObj; i++) if (!ignore[i] && (fProg || FThing(i))) {
- s1 = SFromZ(cp1.obj[i])-1;
- s2 = SFromZ(cp2.obj[i])-1;
-
- /* Does the current planet change into the next or previous sign? */
-
- if (!ignore[i] && s1 != s2 && !ignore[0]) {
- source[occurcount] = i;
- aspect[occurcount] = aSig;
- dest[occurcount] = s2+1;
- time[occurcount] = MinDistance(cp1.obj[i],
- (real)(cp1.dir[i] >= 0.0 ? s2 : s1) * 30.0) /
- MinDistance(cp1.obj[i], cp2.obj[i])*divsiz + (real)(div-1)*divsiz;
- sign1[occurcount] = sign2[occurcount] = s1+1;
- occurcount++;
- }
-
- /* Does the current planet go retrograde or direct? */
-
- if (!ignore[i] && (cp1.dir[i] < 0.0) != (cp2.dir[i] < 0.0) &&
- !ignore2[0]) {
- source[occurcount] = i;
- aspect[occurcount] = aDir;
- dest[occurcount] = cp2.dir[i] < 0.0;
- time[occurcount] = RAbs(cp1.dir[i])/(RAbs(cp1.dir[i])+
- RAbs(cp2.dir[i]))*divsiz + (real)(div-1)*divsiz;
- sign1[occurcount] = sign2[occurcount] = s1+1;
- occurcount++;
- }
-
- /* Now search for anything making an aspect to the current planet. */
-
- for (j = i+1; j <= cObj; j++) if (!ignore[j] && (fProg || FThing(j)))
- for (k = 1; k <= us.nAsp; k++) if (FAcceptAspect(i, k, j)) {
- d1 = cp1.obj[i]; d2 = cp2.obj[i];
- e1 = cp1.obj[j]; e2 = cp2.obj[j];
- if (MinDistance(d1, d2) < MinDistance(e1, e2)) {
- SwapR(&d1, &e1);
- SwapR(&d2, &e2);
- }
-
- /* We are searching each aspect in turn. Let's subtract the */
- /* size of the aspect from the angular difference, so we can */
- /* then treat it like a conjunction. */
-
- if (MinDistance(e1, Mod(d1-aspectangle[k])) <
- MinDistance(e2, Mod(d2+aspectangle[k]))) {
- e1 = Mod(e1+aspectangle[k]);
- e2 = Mod(e2+aspectangle[k]);
- } else {
- e1 = Mod(e1-aspectangle[k]);
- e2 = Mod(e2-aspectangle[k]);
- }
-
- /* Check to see if the aspect actually occurs during our */
- /* segment, making sure we take into account if one or both */
- /* planets are retrograde or if they cross the Aries point. */
-
- f1 = e1-d1;
- if (RAbs(f1) > rDegHalf)
- f1 -= RSgn(f1)*rDegMax;
- f2 = e2-d2;
- if (RAbs(f2) > rDegHalf)
- f2 -= RSgn(f2)*rDegMax;
- if (MinDistance(Midpoint(d1, d2), Midpoint(e1, e2)) < rDegQuad &&
- RSgn(f1) != RSgn(f2)) {
- source[occurcount] = i;
- aspect[occurcount] = k;
- dest[occurcount] = j;
-
- /* Horray! The aspect occurs sometime during the interval. */
- /* Now we just have to solve an equation in two variables to */
- /* find out where the "lines" cross, i.e. the aspect's time. */
-
- f1 = d2-d1;
- if (RAbs(f1) > rDegHalf)
- f1 -= RSgn(f1)*rDegMax;
- f2 = e2-e1;
- if (RAbs(f2) > rDegHalf)
- f2 -= RSgn(f2)*rDegMax;
- g = (RAbs(d1-e1) > rDegHalf ?
- (d1-e1)-RSgn(d1-e1)*rDegMax : d1-e1)/(f2-f1);
- time[occurcount] = g*divsiz + (real)(div-1)*divsiz;
- sign1[occurcount] = (int)(Mod(cp1.obj[i]+
- RSgn(cp2.obj[i]-cp1.obj[i])*
- (RAbs(cp2.obj[i]-cp1.obj[i]) > rDegHalf ? -1 : 1)*
- RAbs(g)*MinDistance(cp1.obj[i], cp2.obj[i]))/30.0)+1;
- sign2[occurcount] = (int)(Mod(cp1.obj[j]+
- RSgn(cp2.obj[j]-cp1.obj[j])*
- (RAbs(cp2.obj[j]-cp1.obj[j]) > rDegHalf ? -1 : 1)*
- RAbs(g)*MinDistance(cp1.obj[j], cp2.obj[j]))/30.0)+1;
- occurcount++;
- }
- }
- }
- }
-
- /* After all the aspects, etc, in the day have been located, sort */
- /* them by time at which they occur, so we can print them in order. */
-
- for (i = 1; i < occurcount; i++) {
- j = i-1;
- while (j >= 0 && time[j] > time[j+1]) {
- SwapN(source[j], source[j+1]);
- SwapN(aspect[j], aspect[j+1]);
- SwapN(dest[j], dest[j+1]);
- SwapR(&time[j], &time[j+1]);
- SwapN(sign1[j], sign1[j+1]); SwapN(sign2[j], sign2[j+1]);
- j--;
- }
- }
-
- /* Finally, loop through and display each aspect and when it occurs. */
-
- for (i = 0; i < occurcount; i++) {
- s1 = (int)time[i]/60;
- s2 = (int)time[i]-s1*60;
- j = Day2;
- if (fYear || fProg) {
- l = Mon2;
- while (j > (k = DayInMonth(l, yea0))) {
- j -= k;
- l++;
- }
- }
- SetCI(ciSave, fYear || fProg ? l : Mon, j, yea0,
- DegToDec(time[i] / 60.0), Dst, Zon, Lon, Lat);
- k = DayOfWeek(fYear || fProg ? l : Mon, j, yea0);
- AnsiColor(kRainbowA[k + 1]);
- sprintf(sz, "(%c%c%c) ", chDay3(k)); PrintSz(sz);
- AnsiColor(kDefault);
- sprintf(sz, "%s %s ",
- SzDate(fYear || fProg ? l : Mon, j, yea0, fFalse),
- SzTime(s1, s2)); PrintSz(sz);
- PrintAspect(source[i], sign1[i],
- (int)RSgn(cp1.dir[source[i]])+(int)RSgn(cp2.dir[source[i]]),
- aspect[i], dest[i], sign2[i],
- (int)RSgn(cp1.dir[dest[i]])+(int)RSgn(cp2.dir[dest[i]]),
- (char)(fProg ? 'e' : 'd'));
- PrintInDay(source[i], aspect[i], dest[i]);
- }
- }
- }
-
- /* Recompute original chart placements as we've overwritten them. */
-
- ciCore = ciMain;
- CastChart(fTrue);
- }
-
-
- /* Search through a month, year, or years, and print out the times of exact */
- /* transits where planets in the time frame make aspect to the planets in */
- /* some other chart, as specified with the -t switch. To do this, we cast */
- /* charts for the start and end of each month, or within a month, and do an */
- /* equation check for aspects to the other base chart during the interval. */
-
- void ChartTransitSearch(fProg)
- bool fProg;
- {
- real planet3[objMax], house3[cSign+1], ret3[objMax], time[MAXINDAY];
- char sz[cchSzDef];
- int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY], sign[MAXINDAY],
- isret[MAXINDAY], M1, M2, Y1, Y2, occurcount, div, i, j, k, s1, s2, s3;
- real divsiz, daysiz, d, e1, e2, f1, f2;
-
- for (i = 1; i <= cSign; i++)
- house3[i] = house[i];
- for (i = 1; i <= cObj; i++) {
- planet3[i] = planet[i];
- ret3[i] = ret[i];
- }
-
- /* Hacks: Searching month number zero means to search the whole year */
- /* instead, month by month. Searching a negative month means to search */
- /* multiple years, with the span off the year stored in the "day" field. */
-
- Y1 = Y2 = Yea2;
- M1 = M2 = Mon2;
- if (Mon2 < 1) {
- M1 = 1; M2 = 12;
- if (Mon2 < 0) {
- if (Day2 < 1) {
- Y1 = Yea2 + Day2 + 1; Y2 = Yea2;
- } else {
- Y1 = Yea2; Y2 = Yea2 + Day2 - 1;
- }
- }
- }
-
- /* Start searching the year or years in question for any transits. */
-
- for (Yea2 = Y1; Yea2 <= Y2; Yea2++)
-
- /* Start searching the month or months in question for any transits. */
-
- for (Mon2 = M1; Mon2 <= M2; Mon2++) {
- daysiz = (real)DayInMonth(Mon2, Yea2)*24.0*60.0;
- divsiz = daysiz / (real)us.nDivision;
-
- /* Cast chart for beginning of month and store it for future use. */
-
- SetCI(ciCore, Mon2, 1, Yea2, 0.0, Dst2, Zon2, Lon2, Lat2);
- if (us.fProgress = fProg) {
- is.JDp = MdytszToJulian(MM, DD, YY, 0.0, Dst2, Zon2);
- ciCore = ciMain;
- }
- for (i = 1; i <= oNorm; i++)
- SwapN(ignore[i], ignore2[i]);
- CastChart(fTrue);
- for (i = 1; i <= oNorm; i++)
- SwapN(ignore[i], ignore2[i]);
- for (i = 1; i <= cSign; i++)
- cp2.cusp[i] = house[i];
- for (i = 1; i <= oCore; i++) {
- cp2.obj[i] = planet[i];
- cp2.dir[i] = ret[i];
- }
-
- /* Divide our month into segments and then search each segment in turn. */
-
- for (div = 1; div <= us.nDivision; div++) {
- occurcount = 0;
-
- /* Cast the chart for the ending time of the present segment, and */
- /* copy the start time chart from the previous end time chart. */
-
- d = 1.0 + (daysiz/24.0/60.0)*(real)div/(real)us.nDivision;
- SetCI(ciCore, Mon2, (int)d, Yea2,
- DegToDec(RFract(d)*24.0), Dst2, Zon2, Lon2, Lat2);
- if (fProg) {
- is.JDp = MdytszToJulian(MM, DD, YY, 0.0, Dst2, Zon2);
- ciCore = ciMain;
- }
- for (i = 1; i <= oNorm; i++)
- SwapN(ignore[i], ignore2[i]);
- CastChart(fTrue);
- for (i = 1; i <= oNorm; i++)
- SwapN(ignore[i], ignore2[i]);
- for (i = 1; i <= cSign; i++) {
- cp1.cusp[i] = cp2.cusp[i]; cp2.cusp[i] = house[i];
- }
- for (i = 1; i <= oCore; i++) {
- cp1.obj[i] = cp2.obj[i]; cp1.dir[i] = cp2.dir[i];
- cp2.obj[i] = planet[i]; cp2.dir[i] = ret[i];
- }
-
- /* Now search through the present segment for any transits. Note that */
- /* stars can be transited, but they can't make transits themselves. */
-
- for (i = 1; i <= cObj; i++) if (!ignore[i])
- for (j = 1; j <= oNorm; j++) if (!ignore2[j] && (fProg || FThing(j)))
-
- /* Between each pair of planets, check if they make any aspects. */
-
- for (k = 1; k <= us.nAsp; k++) if (FAcceptAspect(i, k, j)) {
- d = planet3[i]; e1 = cp1.obj[j]; e2 = cp2.obj[j];
- if (MinDistance(e1, Mod(d-aspectangle[k])) <
- MinDistance(e2, Mod(d+aspectangle[k]))) {
- e1 = Mod(e1+aspectangle[k]);
- e2 = Mod(e2+aspectangle[k]);
- } else {
- e1 = Mod(e1-aspectangle[k]);
- e2 = Mod(e2-aspectangle[k]);
- }
-
- /* Check to see if the present aspect actually occurs during the */
- /* segment, making sure we check any Aries point crossings. */
-
- f1 = e1-d;
- if (RAbs(f1) > rDegHalf)
- f1 -= RSgn(f1)*rDegMax;
- f2 = e2-d;
- if (RAbs(f2) > rDegHalf)
- f2 -= RSgn(f2)*rDegMax;
- if (MinDistance(d, Midpoint(e1, e2)) < rDegQuad &&
- RSgn(f1) != RSgn(f2) && occurcount < MAXINDAY) {
-
- /* Ok, we have found a transit. Now determine the time */
- /* and save this transit in our list to be printed. */
-
- source[occurcount] = j;
- aspect[occurcount] = k;
- dest[occurcount] = i;
- time[occurcount] = RAbs(f1)/(RAbs(f1)+RAbs(f2))*divsiz +
- (real)(div-1)*divsiz;
- sign[occurcount] = (int)(Mod(
- MinDistance(cp1.obj[j], Mod(d-aspectangle[k])) <
- MinDistance(cp2.obj[j], Mod(d+aspectangle[k])) ?
- d-aspectangle[k] : d+aspectangle[k])/30.0)+1;
- isret[occurcount] = (int)RSgn(cp1.dir[j]) +
- (int)RSgn(cp2.dir[j]);
- occurcount++;
- }
- }
-
- /* After all transits located, sort them by time at which they occur. */
-
- for (i = 1; i < occurcount; i++) {
- j = i-1;
- while (j >= 0 && time[j] > time[j+1]) {
- SwapN(source[j], source[j+1]);
- SwapN(aspect[j], aspect[j+1]);
- SwapN(dest[j], dest[j+1]);
- SwapR(&time[j], &time[j+1]);
- SwapN(sign[j], sign[j+1]);
- SwapN(isret[j], isret[j+1]);
- j--;
- }
- }
-
- /* Now loop through list and display all the transits. */
-
- for (i = 0; i < occurcount; i++) {
- s1 = (_int)time[i]/24/60;
- s3 = (_int)time[i]-s1*24*60;
- s2 = s3/60;
- s3 = s3-s2*60;
- SetCI(ciSave, Mon2, s1+1, Yea2, DegToDec((real)
- ((_int)time[i]-s1*24*60) / 60.0), Dst2, Zon2, Lon2, Lat2);
- sprintf(sz, "%s %s ",
- SzDate(Mon2, s1+1, Yea2, fFalse), SzTime(s2, s3)); PrintSz(sz);
- PrintAspect(source[i], sign[i], isret[i], aspect[i],
- dest[i], SFromZ(planet3[dest[i]]), (int)RSgn(ret3[dest[i]]),
- (char)(fProg ? 'u' : 't'));
-
- /* Check for a Solar, Lunar, or any other return. */
-
- if (aspect[i] == aCon && source[i] == dest[i]) {
- AnsiColor(kWhite);
- sprintf(sz, " (%s Return)", source[i] == oSun ? "Solar" :
- (source[i] == oMoo ? "Lunar" : szObjName[source[i]]));
- PrintSz(sz);
- }
- PrintL();
- #ifdef INTERPRET
- if (us.fInterpret)
- InterpretTransit(source[i], aspect[i], dest[i]);
- #endif
- AnsiColor(kDefault);
- }
- }
- }
- }
-
-
- /* Display a list of planetary rising times relative to the local horizon */
- /* for the day indicated in the chart information, as specified with the */
- /* -Zd switch. For the day, the time each planet rises (transits horizon */
- /* in East half of sky), sets (transits horizon in West), reaches its */
- /* zenith point (transits meridian in South half of sky), and nadirs */
- /* transits meridian in North), is displayed. */
-
- void ChartInDayHorizon()
- {
- char sz[cchSzDef];
- int source[MAXINDAY], type[MAXINDAY], sign[MAXINDAY],
- fRet[MAXINDAY], occurcount, division, div, s1, s2, i, j, fT;
- real time[MAXINDAY], rgalt1[objMax], rgalt2[objMax], azialt[MAXINDAY],
- azi1, azi2, alt1, alt2, lon, lat, mc1, mc2, xA, yA, xV, yV, d, k;
-
- fT = us.fSiderial; us.fSiderial = fFalse;
- lon = RFromD(Mod(Lon)); lat = RFromD(Lat);
- division = us.nDivision * 4;
- occurcount = 0;
-
- ciCore = ciMain; ciCore.tim = 0.0;
- CastChart(fTrue);
- mc2 = RFromD(planet[oMC]); k = RFromD(planetalt[oMC]);
- EclToEqu(&mc2, &k);
- for (i = 1; i <= cSign; i++) {
- cp2.cusp[i] = house[i];
- cp2.house[i] = inhouse[i];
- }
- for (i = 1; i <= cObj; i++) {
- cp2.obj[i] = planet[i];
- rgalt2[i] = planetalt[i];
- cp2.dir[i] = ret[i];
- }
-
- /* Loop thorough the day, dividing it into a certain number of segments. */
- /* For each segment we get the planet positions at its endpoints. */
-
- for (div = 1; div <= division; div++) {
- ciCore = ciMain; ciCore.tim = DegToDec(24.0*(real)div/(real)division);
- CastChart(fTrue);
- mc1 = mc2;
- mc2 = RFromD(planet[oMC]); k = RFromD(planetalt[oMC]);
- EclToEqu(&mc2, &k);
- for (i = 1; i <= cSign; i++) {
- cp1.cusp[i] = cp2.cusp[i]; cp1.house[i] = cp2.house[i];
- cp2.cusp[i] = house[i]; cp2.house[i] = inhouse[i];
- }
- for (i = 1; i <= cObj; i++) {
- cp1.obj[i] = cp2.obj[i]; cp2.obj[i] = planet[i];
- rgalt1[i] = rgalt2[i]; rgalt2[i] = planetalt[i];
- cp1.dir[i] = cp2.dir[i]; cp2.dir[i] = ret[i];
- }
-
- /* For our segment, check to see if each planet during it rises, sets, */
- /* reaches its zenith, or reaches its nadir. */
-
- for (i = 1; i <= cObj; i++) if (!ignore[i] && FThing(i)) {
- EclToHorizon(&azi1, &alt1, cp1.obj[i], rgalt1[i], lon, lat, mc1);
- EclToHorizon(&azi2, &alt2, cp2.obj[i], rgalt2[i], lon, lat, mc2);
- j = 0;
-
- /* Check for transits to the horizon. */
- if ((alt1 > 0.0) != (alt2 > 0.0)) {
- d = RAbs(alt1)/(RAbs(alt1)+RAbs(alt2));
- k = Mod(azi1 + d*MinDifference(azi1, azi2));
- j = 1 + 2*(MinDistance(k, rDegHalf) < rDegQuad);
-
- /* Check for transits to the meridian. */
- } else if (RSgn(MinDifference(azi1, rDegQuad)) !=
- RSgn(MinDifference(azi2, rDegQuad))) {
- j = 2 + 2*(MinDistance(azi1, rDegQuad) < rDegQuad);
- d = RAbs(azi1 - (j > 2 ? rDegQuad : 270.0))/MinDistance(azi1, azi2);
- k = alt1 + d*(alt2-alt1);
- }
- if (j && occurcount < MAXINDAY) {
- source[occurcount] = i;
- type[occurcount] = j;
- time[occurcount] = 24.0*((real)(div-1)+d)/(real)division*60.0;
- sign[occurcount] = (int)Mod(cp1.obj[i] +
- d*MinDifference(cp1.obj[i], cp2.obj[i]))/30 + 1;
- fRet[occurcount] = (int)RSgn(cp1.dir[i]) + (int)RSgn(cp2.dir[i]);
- azialt[occurcount] = k;
- ciSave = ciMain;
- ciSave.tim = DegToDec(time[occurcount] / 60.0);
- occurcount++;
- }
- }
- }
-
- /* Sort each event in order of time when it happens during the day. */
-
- for (i = 1; i < occurcount; i++) {
- j = i-1;
- while (j >= 0 && time[j] > time[j+1]) {
- SwapN(source[j], source[j+1]);
- SwapN(type[j], type[j+1]);
- SwapR(&time[j], &time[j+1]);
- SwapN(sign[j], sign[j+1]);
- SwapN(fRet[j], fRet[j+1]);
- SwapR(&azialt[j], &azialt[j+1]);
- j--;
- }
- }
-
- /* Finally display the list showing each event and when it occurs. */
-
- for (i = 0; i < occurcount; i++) {
- ciSave = ciMain;
- ciSave.tim = DegToDec(time[i] / 60.0);
- j = DayOfWeek(Mon, Day, Yea);
- AnsiColor(kRainbowA[j + 1]);
- sprintf(sz, "(%c%c%c) ", chDay3(j)); PrintSz(sz);
- AnsiColor(kDefault);
- s1 = (int)time[i]/60;
- s2 = (int)time[i]-s1*60;
- sprintf(sz, "%s %s ", SzDate(Mon, Day, Yea, fFalse), SzTime(s1, s2));
- PrintSz(sz);
- AnsiColor(kObjA[source[i]]);
- sprintf(sz, "%7.7s ", szObjName[source[i]]); PrintSz(sz);
- AnsiColor(kSignA(sign[i]));
- sprintf(sz, "%c%c%c%c%c ",
- fRet[i] > 0 ? '(' : (fRet[i] < 0 ? '[' : '<'), chSig3(sign[i]),
- fRet[i] > 0 ? ')' : (fRet[i] < 0 ? ']' : '>')); PrintSz(sz);
- AnsiColor(kElemA[type[i]-1]);
- if (type[i] == 1)
- PrintSz("rises ");
- else if (type[i] == 2)
- PrintSz("zeniths");
- else if (type[i] == 3)
- PrintSz("sets ");
- else
- PrintSz("nadirs ");
- AnsiColor(kDefault);
- PrintSz(" at ");
- if (type[i] & 1) {
- j = (int)(RFract(azialt[i])*60.0);
- sprintf(sz, "%3d%c%02d'", (int)azialt[i], chDeg1, j); PrintSz(sz);
-
- /* For rising and setting events, we'll also display a direction */
- /* vector to make the 360 degree azimuth value thought of easier. */
-
- xA = RCosD(azialt[i]); yA = RSinD(azialt[i]);
- if (RAbs(xA) < RAbs(yA)) {
- xV = RAbs(xA / yA); yV = 1.0;
- } else {
- yV = RAbs(yA / xA); xV = 1.0;
- }
- sprintf(sz, " (%.2f%c %.2f%c)",
- yV, yA < 0.0 ? 's' : 'n', xV, xA > 0.0 ? 'e' : 'w'); PrintSz(sz);
- } else
- PrintAltitude(azialt[i]);
- PrintL();
- }
-
- /* Recompute original chart placements as we've overwritten them. */
-
- ciCore = ciMain;
- us.fSiderial = fT;
- CastChart(fTrue);
- }
-
-
- /* Print out an ephemeris - the positions of the planets (at the time in the */
- /* current chart) each day during a specified month, as done with the -E */
- /* switch. Display the ephemeris for the whole year if -Ey is in effect. */
-
- void ChartEphemeris()
- {
- char sz[cchSzDef];
- int yea, yea1, yea2, mon, mon1, mon2, daysiz, i, j, s, d, m;
-
- /* If -Ey is in effect, then loop through all months in the whole year. */
-
- if (us.nEphemYears) {
- yea1 = Yea; yea2 = yea1 + us.nEphemYears - 1; mon1 = 1; mon2 = 12;
- } else {
- yea1 = yea2 = Yea; mon1 = mon2 = Mon;
- }
-
- /* Loop through the year or years in question. */
-
- for (yea = yea1; yea <= yea2; yea++)
-
- /* Loop through the month or months in question, printing each ephemeris. */
-
- for (mon = mon1; mon <= mon2; mon++) {
- daysiz = DayInMonth(mon, yea);
- PrintSz(us.fEuroDate ? "Dy/Mo/Yr" : "Mo/Dy/Yr");
- for (j = 1; j <= cObj; j++) {
- if (!ignore[j] && FThing(j)) {
- sprintf(sz, " %s%c%c%c%c%s ", is.fSeconds ? " " : "", chObj3(j),
- szObjName[j][3] != 0 ? szObjName[j][3] : ' ',
- is.fSeconds ? " " : ""); PrintSz(sz);
- }
- }
- PrintL();
- for (i = 1; i <= daysiz; i = AddDay(mon, i, yea, 1)) {
-
- /* Loop through each day in the month, casting a chart for that day. */
-
- SetCI(ciCore, mon, i, yea, Tim, Dst, Zon, Lon, Lat);
- CastChart(fTrue);
- PrintSz(SzDate(mon, i, yea, -1));
- PrintCh(' ');
- for (j = 1; j <= cObj; j++)
- if (!ignore[j] && FThing(j)) {
- if (is.fSeconds)
- PrintZodiac(planet[j]);
- else {
- AnsiColor(kObjA[j]);
- s = SFromZ(planet[j]);
- d = (int)planet[j] - (s-1)*30;
- m = (int)(RFract(planet[j])*60.0);
- sprintf(sz, "%2d%s%02d", d, szSignAbbrev[s], m); PrintSz(sz);
- }
- PrintCh((char)(ret[j] >= 0.0 ? ' ' : '.'));
- }
- PrintL();
- AnsiColor(kDefault);
- }
- if (mon < mon2 || yea < yea2)
- PrintL();
- }
- }
-
- /* charts3.c */
-